package com.heima.wemedia.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.constants.WmMaterialConstants;
import com.heima.file.service.FileStorageService;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dtos.WmMaterialDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.utils.thread.WmThreadLocalUtil;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.WmMaterialService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 自媒体图文素材信息表 服务实现类
 * </p>
 *
 * @author An
 */
@Slf4j
@Service
@Transactional
public class WmMaterialServiceImpl extends ServiceImpl<WmMaterialMapper, WmMaterial> implements WmMaterialService {

    @Autowired
    private FileStorageService fileStorageService;

    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    /**
     * 图片上传
     *
     * @param multipartFile
     * @return
     */
    @Override
    public ResponseResult uploadPicture(MultipartFile multipartFile) {
        // 检查参数
        if (multipartFile == null || multipartFile.getSize() == 0) {
            // 返回参数错误
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        // 上传到MinIO中
        // 使用UUID随机生成文件名,防止文件名重复导致文件被覆盖
        String fileName = UUID.randomUUID().toString().replaceAll("-", "");
        // 获取到multipartFile中的文件名,截取到文件后缀
        String originalFilename = multipartFile.getOriginalFilename();
        if (originalFilename != null) {
            // 拼接成为新的文件名
            fileName = fileName + originalFilename.substring(originalFilename.lastIndexOf("."));
        }
        String imgFilePath = "";
        try {
            // 上传文件
            imgFilePath = fileStorageService.uploadImgFile("", fileName, multipartFile.getInputStream());
            log.info("上传图片到MinIO中，imgFilePath:{}", imgFilePath);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("WmMaterialServiceImpl-上传文件失败");
        }

        // 将文件路径保存到文件素材表中
        WmMaterial wmMaterial = new WmMaterial();
        Integer id = WmThreadLocalUtil.getUser().getId();
        // 设置参数
        wmMaterial.setCreatedTime(new Date());
        wmMaterial.setUserId(id);
        wmMaterial.setUrl(imgFilePath);
        wmMaterial.setType(WmMaterialConstants.TYPE_PICTURE);
        wmMaterial.setIsCollection(WmMaterialConstants.NOT_COLLECTION);
        // 保存
        save(wmMaterial);

        return ResponseResult.okResult(wmMaterial);
    }

    /**
     * 素材分页查询
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult findList(WmMaterialDto dto) {
        // 参数校验
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        // 分页参数校正
        dto.checkParam();
        // 分页查询
        IPage<WmMaterial> page = new Page<>(dto.getPage(), dto.getSize());
        // 添加查询条件
        LambdaQueryWrapper<WmMaterial> queryWrapper = new LambdaQueryWrapper<>();
        // 是否被收藏
        if (dto.getIsCollection() != null && dto.getIsCollection() == 1) {
            queryWrapper.eq(WmMaterial::getIsCollection, dto.getIsCollection());
        }
        // 查询当前登录用户的素材
        queryWrapper.eq(WmMaterial::getUserId, WmThreadLocalUtil.getUser().getId());
        // 添加排序条件
        queryWrapper.orderByDesc(WmMaterial::getCreatedTime);

        // 查询
        page = page(page, queryWrapper);

        // 返回结果
        PageResponseResult result = new PageResponseResult();
        result.setCurrentPage((int)page.getCurrent());
        result.setSize((int)page.getSize());
        result.setTotal((int)page.getTotal());
        result.setData(page.getRecords());

        return result;
    }

    /**
     * 删除素材
     *
     * @param id 素材id
     * @return
     */
    @Override
    public ResponseResult delPicture(Integer id) {
        // 参数校验
        if (id == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        // 如果素材被引用则不能删除
        // 根据素材id查询到素材
        WmMaterial wmMaterial = getById(id);
        if (wmMaterial == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        // 判断素材是否被引用,去文章素材关系表中查询
        List<WmNewsMaterial> newsMaterialList = wmNewsMaterialMapper
                .selectList(Wrappers.<WmNewsMaterial>lambdaQuery()
                .eq(WmNewsMaterial::getMaterialId, id)
        );

        if (newsMaterialList.size() > 0) {
            // 素材被引用,不能删除
            return ResponseResult.errorResult(501, "素材已被引用,不能删除");
        }

        // 代码走到这则素材可以被删除
        // 先删除MinIO中的素材,再删除数据库中的Url
        fileStorageService.delete(wmMaterial.getUrl());
        removeById(id);

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 素材收藏或取消收藏
     *
     * @param id 素材id
     * @return
     */
    @Override
    public ResponseResult collectOrCancelCollect(Integer id) {
        // 参数校验
        if (id == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        // 从数据库中查询到当前素材
        WmMaterial wmMaterial = getById(id);

        // 判断当前操作是要收藏还是取消收藏
        if (WmMaterialConstants.IS_COLLECTION.equals(wmMaterial.getIsCollection())) {
            // 要取消收藏
            wmMaterial.setIsCollection(WmMaterialConstants.NOT_COLLECTION);
        }else{
            // 要收藏
            wmMaterial.setIsCollection(WmMaterialConstants.IS_COLLECTION);
        }

        // 更新数据库状态
        updateById(wmMaterial);

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
}
